home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / benchmarks / itc / cc1.spur / rtl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-30  |  25.8 KB  |  1,147 lines

  1. /* Manage RTL for C-Compiler
  2.    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY.  No author or distributor
  8. accepts responsibility to anyone for the consequences of using it
  9. or for whether it serves any particular purpose or works at all,
  10. unless he says so in writing.  Refer to the GNU CC General Public
  11. License for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. GNU CC, but only under the conditions described in the
  15. GNU CC General Public License.   A copy of this license is
  16. supposed to have been given to you along with GNU CC so you
  17. can know your rights and responsibilities.  It should be in a
  18. file named COPYING.  Among other things, the copyright notice
  19. and this notice must be preserved on all copies.  */
  20.  
  21.  
  22. /* This file contains the low level primitives for allocating,
  23.    printing and reading rtl expressions and vectors.
  24.    It also contains some functions for semantic analysis
  25.    on rtl expressions.  */
  26.  
  27. #include "config.h"
  28. #include <ctype.h>
  29. #include <stdio.h>
  30. #include "rtl.h"
  31. #include "alloca.h"
  32.  
  33. #include "obstack.h"
  34. #define    obstack_chunk_alloc    xmalloc
  35. #define    obstack_chunk_free    free
  36. extern int xmalloc ();
  37. extern void free ();
  38.  
  39. /* Obstack used for allocating RTL objects.
  40.    Between functions, this is the permanent_obstack.
  41.    While parsing and expanding a function, this is maybepermanent_obstack
  42.    so we can save it if it is an inline function.
  43.    During optimization and output, this is temporary_obstack.  */
  44.  
  45. extern struct obstack *rtl_obstack;
  46.  
  47. #define MIN(x,y) ((x < y) ? x : y)
  48.  
  49. extern long ftell();
  50.  
  51. /* Indexed by rtx code, gives number of operands for an rtx with that code.
  52.    Does NOT include rtx header data (code and links).
  53.    This array is initialized in init_rtx.  */
  54.  
  55. int rtx_length[NUM_RTX_CODE + 1];
  56.  
  57. /* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
  58.  
  59. #define DEF_RTL_EXPR(ENUM, NAME, FORMAT)   NAME ,
  60.  
  61. char *rtx_name[] = {
  62. #include "rtl.def"        /* rtl expressions are documented here */
  63. };
  64.  
  65. #undef DEF_RTL_EXPR
  66.  
  67. /* Indexed by machine mode, gives the name of that machine mode.
  68.    This name does not include the letters "mode".  */
  69.  
  70. #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  NAME,
  71.  
  72. char *mode_name[] = {
  73. #include "machmode.def"
  74. };
  75.  
  76. #undef DEF_MACHMODE
  77.  
  78. /* Indexed by machine mode, gives the length of the mode, in bytes.
  79.    GET_MODE_CLASS uses this.  */
  80.  
  81. #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  CLASS,
  82.  
  83. enum mode_class mode_class[] = {
  84. #include "machmode.def"
  85. };
  86.  
  87. #undef DEF_MACHMODE
  88.  
  89. /* Indexed by machine mode, gives the length of the mode, in bytes.
  90.    GET_MODE_SIZE uses this.  */
  91.  
  92. #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  SIZE,
  93.  
  94. int mode_size[] = {
  95. #include "machmode.def"
  96. };
  97.  
  98. #undef DEF_MACHMODE
  99.  
  100. /* Indexed by machine mode, gives the length of the mode's subunit.
  101.    GET_MODE_UNIT_SIZE uses this.  */
  102.  
  103. #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT)  UNIT,
  104.  
  105. int mode_unit_size[] = {
  106. #include "machmode.def"        /* machine modes are documented here */
  107. };
  108.  
  109. #undef DEF_MACHMODE
  110.  
  111. /* Indexed by rtx code, gives a sequence of operand-types for
  112.    rtx's of that code.  The sequence is a C string in which
  113.    each charcter describes one operand.  */
  114.  
  115. char *rtx_format[] = {
  116.   /* "*" undefined.
  117.          can cause a warning message
  118.      "0" field is unused (or used in a phase-dependent manner)
  119.          prints nothing
  120.      "i" an integer
  121.          prints the integer
  122.      "s" a pointer to a string
  123.          prints the string
  124.      "e" a pointer to an rtl expression
  125.          prints the expression
  126.      "E" a pointer to a vector that points to a number of rtl expressions
  127.          prints a list of the rtl expressions
  128.      "u" a pointer to another insn
  129.          prints the uid of the insn.  */
  130.  
  131. #define DEF_RTL_EXPR(ENUM, NAME, FORMAT)   FORMAT ,
  132. #include "rtl.def"        /* rtl expressions are defined here */
  133. #undef DEF_RTL_EXPR
  134. };
  135.  
  136. /* Allocate an rtx vector of N elements.
  137.    Store the length, and initialize all elements to zero.  */
  138.  
  139. rtvec
  140. rtvec_alloc (n)
  141.      int n;
  142. {
  143.   rtvec rt;
  144.   int i;
  145.  
  146.   rt = (rtvec) obstack_alloc (rtl_obstack,
  147.                   sizeof (struct rtvec_def)
  148.                   + (( n - 1) * sizeof (rtunion)));
  149.  
  150.   /* clear out the vector */
  151.   PUT_NUM_ELEM(rt, n);
  152.   for (i=0; i < n; i++)
  153.     rt->elem[i].rtvec = NULL;    /* @@ not portable due to rtunion */
  154.  
  155.   return rt;
  156. }
  157.  
  158. /* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
  159.    all the rest is initialized to zero.  */
  160.  
  161. rtx
  162. rtx_alloc (code)
  163.   RTX_CODE code;
  164. {
  165.   rtx rt;
  166.   register int nelts = GET_RTX_LENGTH (code);
  167.   register int length = sizeof (struct rtx_def)
  168.     + (nelts - 1) * sizeof (rtunion);
  169.  
  170.   rt = (rtx) obstack_alloc (rtl_obstack, length);
  171.  
  172.   * (int *) rt = 0;
  173.   PUT_CODE (rt, code);
  174.  
  175.   return rt;
  176. }
  177.  
  178. /* Create a new copy of an rtx.
  179.    Recursively copies the operands of the rtx,
  180.    except for those few rtx codes that are sharable.  */
  181.  
  182. rtx
  183. copy_rtx (orig)
  184.      register rtx orig;
  185. {
  186.   register rtx copy;
  187.   register int i, j;
  188.   register RTX_CODE code;
  189.   register char *format_ptr;
  190.  
  191.   code = GET_CODE (orig);
  192.  
  193.   switch (code)
  194.     {
  195.     case REG:
  196.     case QUEUED:
  197.     case CONST_INT:
  198.     case CONST_DOUBLE:
  199.     case SYMBOL_REF:
  200.     case CODE_LABEL:
  201.     case PC:
  202.     case CC0:
  203.       return orig;
  204.     }
  205.  
  206.   copy = rtx_alloc (code);
  207.   PUT_MODE (copy, GET_MODE (orig));
  208.   copy->in_struct = orig->in_struct;
  209.   copy->volatil = orig->volatil;
  210.   copy->unchanging = orig->unchanging;
  211.   copy->integrated = orig->integrated;
  212.   
  213.   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
  214.  
  215.   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
  216.     {
  217.       switch (*format_ptr++)
  218.     {
  219.     case 'e':
  220.       XEXP (copy, i) = copy_rtx (XEXP (orig, i));
  221.       break;
  222.  
  223.     case 'E':
  224.       XVEC (copy, i) = XVEC (orig, i);
  225.       if (XVEC (orig, i) != NULL)
  226.         {
  227.           XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
  228.           for (j = 0; j < XVECLEN (copy, i); j++)
  229.         XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
  230.         }
  231.       break;
  232.  
  233.     default:
  234.       XINT (copy, i) = XINT (orig, i);
  235.       break;
  236.     }
  237.     }
  238.   return copy;
  239. }
  240.  
  241. /* Return 1 if the value of X is unstable
  242.    (would be different at a different point in the program).
  243.    The frame pointer, arg pointer, etc. are considered stable
  244.    (within one function) and so is anything marked `unchanging'.  */
  245.  
  246. int
  247. rtx_unstable_p (x)
  248.      rtx x;
  249. {
  250.   register RTX_CODE code = GET_CODE (x);
  251.   register int i;
  252.   register char *fmt;
  253.  
  254.   if (code == MEM)
  255.     return ! x->unchanging;
  256.  
  257.   if (code == QUEUED)
  258.     return 1;
  259.  
  260.   if (code == CONST || code == CONST_INT)
  261.     return 0;
  262.  
  263.   if (code == REG)
  264.     return ! (REGNO (x) == FRAME_POINTER_REGNUM
  265.           || REGNO (x) == ARG_POINTER_REGNUM
  266.           || x->unchanging);
  267.  
  268.   fmt = GET_RTX_FORMAT (code);
  269.   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  270.     if (fmt[i] == 'e')
  271.       if (rtx_unstable_p (XEXP (x, i)))
  272.     return 1;
  273.   return 0;
  274. }
  275.  
  276. /* Return 1 if X has a value that can vary even between two
  277.    executions of the program.  0 means X can be compared reliably
  278.    against certain constants or near-constants.
  279.    The frame pointer and the arg pointer are considered constant.  */
  280.  
  281. int
  282. rtx_varies_p (x)
  283.      rtx x;
  284. {
  285.   register RTX_CODE code = GET_CODE (x);
  286.   register int i;
  287.   register char *fmt;
  288.  
  289.   if (code == MEM)
  290.     return 1;
  291.  
  292.   if (code == QUEUED)
  293.     return 1;
  294.  
  295.   if (code == CONST || code == CONST_INT)
  296.     return 0;
  297.  
  298.   if (code == REG)
  299.     return ! (REGNO (x) == FRAME_POINTER_REGNUM
  300.           || REGNO (x) == ARG_POINTER_REGNUM);
  301.  
  302.   fmt = GET_RTX_FORMAT (code);
  303.   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  304.     if (fmt[i] == 'e')
  305.       if (rtx_varies_p (XEXP (x, i)))
  306.     return 1;
  307.   return 0;
  308. }
  309.  
  310. /* Return 1 if X refers to a memory location whose address 
  311.    cannot be compared reliably with constant addresses,
  312.    or if X refers to a BLKmode memory object.  */
  313.  
  314. int
  315. rtx_addr_varies_p (x)
  316.      rtx x;
  317. {
  318.   register RTX_CODE code = GET_CODE (x);
  319.   register int i;
  320.   register char *fmt;
  321.  
  322.   if (code == MEM)
  323.     return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
  324.  
  325.   fmt = GET_RTX_FORMAT (code);
  326.   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  327.     if (fmt[i] == 'e')
  328.       if (rtx_addr_varies_p (XEXP (x, i)))
  329.     return 1;
  330.   return 0;
  331. }
  332.  
  333. /* Nonzero if register REG appears somewhere within IN.
  334.    Also works if REG is not a register; in this case it checks
  335.    for a subexpression of IN that is Lisp "equal" to REG.  */
  336.  
  337. int
  338. reg_mentioned_p (reg, in)
  339.      register rtx reg, in;
  340. {
  341.   register char *fmt;
  342.   register int i;
  343.   register enum rtx_code code;
  344.  
  345.   if (in == 0)
  346.     return 0;
  347.  
  348.   if (reg == in)
  349.     return 1;
  350.  
  351.   code = GET_CODE (in);
  352.  
  353.   switch (code)
  354.     {
  355.       /* Compare registers by number.  */
  356.     case REG:
  357.       return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
  358.  
  359.       /* These codes have no constituent expressions
  360.      and are unique.  */
  361.     case CC0:
  362.     case PC:
  363.     case CONST_INT:
  364.     case CONST:
  365.     case CONST_DOUBLE:
  366.     case LABEL_REF:
  367.     case SYMBOL_REF:
  368.       return 0;
  369.     }
  370.  
  371.   if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
  372.     return 1;
  373.  
  374.   fmt = GET_RTX_FORMAT (code);
  375.  
  376.   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  377.     {
  378.       if (fmt[i] == 'E')
  379.     {
  380.       register int j;
  381.       for (j = XVECLEN (in, i) - 1; j >= 0; j--)
  382.         if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
  383.           return 1;
  384.     }
  385.       else if (fmt[i] == 'e'
  386.            && reg_mentioned_p (reg, XEXP (in, i)))
  387.     return 1;
  388.     }
  389.   return 0;
  390. }
  391.  
  392. /* Nonzero if register REG is used in an insn between
  393.    FROM_INSN and TO_INSN (exclusive of those two).  */
  394.  
  395. int
  396. reg_used_between_p (reg, from_insn, to_insn)
  397.      rtx reg, from_insn, to_insn;
  398. {
  399.   register rtx insn;
  400.   register RTX_CODE code;
  401.   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
  402.     if (((code = GET_CODE (insn)) == INSN
  403.      || code == JUMP_INSN || code == CALL_INSN)
  404.     && reg_mentioned_p (reg, PATTERN (insn)))
  405.       return 1;
  406.   return 0;
  407. }
  408.  
  409. /* Return 1 if X and Y are identical-looking rtx's.
  410.    This is the Lisp function EQUAL for rtx arguments.  */
  411.  
  412. int
  413. rtx_equal_p (x, y)
  414.      rtx x, y;
  415. {
  416.   register int i;
  417.   register int hash = 0;
  418.   register RTX_CODE code = GET_CODE (x);
  419.   register char *fmt;
  420.  
  421.   if (x == y)
  422.     return 1;
  423.  
  424.   /* Rtx's of different codes cannot be equal.  */
  425.   if (code != GET_CODE (y))
  426.     return 0;
  427.  
  428.   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
  429.      (REG:SI x) and (REG:HI x) are NOT equivalent.  */
  430.  
  431.   if (GET_MODE (x) != GET_MODE (y))
  432.     return 0;
  433.  
  434.   /* These three types of rtx's can be compared nonrecursively.  */
  435.   if (code == REG)
  436.     return (REGNO (x) == REGNO (y));
  437.   if (code == LABEL_REF)
  438.     return XEXP (x, 0) == XEXP (y, 0);
  439.   if (code == SYMBOL_REF)
  440.     return XSTR (x, 0) == XSTR (y, 0);
  441.  
  442.   /* Compare the elements.  If any pair of corresponding elements
  443.      fail to match, return 0 for the whole things.  */
  444.  
  445.   fmt = GET_RTX_FORMAT (code);
  446.   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  447.     {
  448.       switch (fmt[i])
  449.     {
  450.     case 'i':
  451.       if (XINT (x, i) != XINT (y, i))
  452.         return 0;
  453.       break;
  454.  
  455.     case 'e':
  456.       if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
  457.         return 0;
  458.       break;
  459.  
  460.     case 's':
  461.       if (strcmp (XSTR (x, i), XSTR (y, i)))
  462.         return 0;
  463.       break;
  464.  
  465.     case '0':
  466.       break;
  467.  
  468.       /* It is believed that rtx's at this level will never
  469.          contain anything but integers and other rtx's,
  470.          except for within LABEL_REFs and SYMBOL_REFs.  */
  471.     default:
  472.       abort ();
  473.     }
  474.     }
  475.   return 1;
  476. }
  477.  
  478. /* Call FUN on each register or MEM that is stored into or clobbered by X.
  479.    (X would be the pattern of an insn).
  480.    FUN receives two arguments:
  481.      the REG, MEM, CC0 or PC being stored in or clobbered,
  482.      the SET or CLOBBER rtx that does the store.  */
  483.      
  484. void
  485. note_stores (x, fun)
  486.      register rtx x;
  487.      void (*fun) ();
  488. {
  489.   if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
  490.     {
  491.       register rtx dest = SET_DEST (x);
  492.       while (GET_CODE (dest) == SUBREG
  493.          || GET_CODE (dest) == ZERO_EXTRACT
  494.          || GET_CODE (dest) == SIGN_EXTRACT
  495.          || GET_CODE (dest) == STRICT_LOW_PART)
  496.     dest = XEXP (dest, 0);
  497.       (*fun) (dest, GET_CODE (x) == CLOBBER);
  498.     }
  499.   else if (GET_CODE (x) == PARALLEL)
  500.     {
  501.       register int i;
  502.       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
  503.     {
  504.       register rtx y = XVECEXP (x, 0, i);
  505.       if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
  506.         {
  507.           register rtx dest = SET_DEST (y);
  508.           while (GET_CODE (dest) == SUBREG
  509.              || GET_CODE (dest) == ZERO_EXTRACT
  510.              || GET_CODE (dest) == SIGN_EXTRACT
  511.              || GET_CODE (dest) == STRICT_LOW_PART)
  512.         dest = XEXP (dest, 0);
  513.           (*fun) (dest, GET_CODE (y) == CLOBBER);
  514.         }
  515.     }
  516.     }
  517. }
  518.  
  519. /* Return nonzero if register REG's old contents don't survive after INSN.
  520.    This can be because REG dies in INSN or because INSN entirely sets REG.
  521.  
  522.    "Entirely set" means set directly and not through a SUBREG,
  523.    ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
  524.  
  525.    REG may be a hard or pseudo reg.  Renumbering is not taken into account,
  526.    but for this use that makes no difference, since regs don't overlap
  527.    during their lifetimes.  Therefore, this function may be used
  528.    at any time after deaths have been computed (in flow.c).  */
  529.  
  530. int
  531. dead_or_set_p (insn, reg)
  532.      rtx insn;
  533.      rtx reg;
  534. {
  535.   register rtx link;
  536.   register int regno = REGNO (reg);
  537.  
  538.   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  539.     if ((REG_NOTE_KIND (link) == REG_DEAD
  540.      || REG_NOTE_KIND (link) == REG_INC)
  541.     && REGNO (XEXP (link, 0)) == regno)
  542.       return 1;
  543.  
  544.   if (GET_CODE (PATTERN (insn)) == SET)
  545.     return SET_DEST (PATTERN (insn)) == reg;
  546.   else if (GET_CODE (PATTERN (insn)) == PARALLEL)
  547.     {
  548.       register int i;
  549.       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
  550.     {
  551.       if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
  552.           && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == reg)
  553.         return 1;
  554.     }
  555.     }
  556.   return 0;
  557. }
  558.  
  559. /* Return the reg-note of kind KIND in insn INSN, if there is one.
  560.    If DATUM is nonzero, look for one whose datum is DATUM.  */
  561.  
  562. rtx
  563. find_reg_note (insn, kind, datum)
  564.      rtx insn;
  565.      enum reg_note kind;
  566.      rtx datum;
  567. {
  568.   register rtx link;
  569.  
  570.   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  571.     if (REG_NOTE_KIND (link) == kind
  572.     && (datum == 0 || datum == XEXP (link, 0)))
  573.       return link;
  574.   return 0;
  575. }
  576.  
  577. /* Return the reg-note of kind KIND in insn INSN which applies to register
  578.    number REGNO, if any.  Return 0 if there is no such reg-note.  */
  579.  
  580. rtx
  581. find_regno_note (insn, kind, regno)
  582.      rtx insn;
  583.      enum reg_note kind;
  584.      int regno;
  585. {
  586.   register rtx link;
  587.  
  588.   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  589.     if (REG_NOTE_KIND (link) == kind
  590.     && REGNO (XEXP (link, 0)) == regno)
  591.       return link;
  592.   return 0;
  593. }
  594.  
  595. /* Nonzero if FROM precedes TO with no intervening labels.  */
  596.  
  597. int
  598. no_labels_between (from, to)
  599.      register rtx from, to;
  600. {
  601.   register rtx p = to;
  602.  
  603.   while (1)
  604.     {
  605.       p = PREV_INSN (p);
  606.       if (p == 0)
  607.     return 0;
  608.       if (p == from)
  609.     return 1;
  610.       if (GET_CODE (p) == CODE_LABEL)
  611.     return 0;
  612.     }
  613. }
  614.  
  615. /* Nonzero if X contains any volatile memory references
  616.    or volatile ASM_OPERANDS expressions.  */
  617.  
  618. int
  619. volatile_refs_p (x)
  620.      rtx x;
  621. {
  622.   register RTX_CODE code;
  623.  
  624.   code = GET_CODE (x);
  625.   switch (code)
  626.     {
  627.     case LABEL_REF:
  628.     case SYMBOL_REF:
  629.     case CONST_INT:
  630.     case CONST:
  631.     case CONST_DOUBLE:
  632.     case CC0:
  633.     case PC:
  634.     case REG:
  635.     case CLOBBER:
  636.     case ASM_INPUT:
  637.     case ADDR_VEC:
  638.     case ADDR_DIFF_VEC:
  639.       return 0;
  640.  
  641.     case CALL:
  642.       return 1;
  643.  
  644.     case MEM:
  645.     case ASM_OPERANDS:
  646.       if (x->volatil)
  647.     return 1;
  648.     }
  649.  
  650.   /* Recursively scan the operands of this expression.  */
  651.  
  652.   {
  653.     register char *fmt = GET_RTX_FORMAT (code);
  654.     register int i;
  655.     
  656.     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  657.       {
  658.     if (fmt[i] == 'e')
  659.       {
  660.         if (volatile_refs_p (XEXP (x, i)))
  661.           return 1;
  662.       }
  663.     if (fmt[i] == 'E')
  664.       {
  665.         register int j;
  666.         for (j = 0; j < XVECLEN (x, i); j++)
  667.           if (volatile_refs_p (XVECEXP (x, i, j)))
  668.         return 1;
  669.       }
  670.       }
  671.   }
  672.   return 0;
  673. }
  674.  
  675. /* Printing rtl for debugging dumps.  */
  676.  
  677. static FILE *outfile;
  678.  
  679. char spaces[] = "                                                                                                                                                                ";
  680.  
  681. static int sawclose = 0;
  682.  
  683. /* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
  684.  
  685. static void
  686. print_rtx (in_rtx)
  687.      register rtx in_rtx;
  688. {
  689.   static int indent;
  690.   register int i, j;
  691.   register char *format_ptr;
  692.  
  693.   if (sawclose)
  694.     {
  695.       fprintf (outfile, "\n%s",
  696.            (spaces + (sizeof spaces - indent * 2)));
  697.       sawclose = 0;
  698.     }
  699.  
  700.   if (in_rtx == 0)
  701.     {
  702.       fprintf (outfile, "(nil)");
  703.       sawclose = 1;
  704.       return;
  705.     }
  706.  
  707.   /* print name of expression code */
  708.   fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
  709.  
  710.   if (in_rtx->in_struct)
  711.     fprintf (outfile, "/s");
  712.  
  713.   if (in_rtx->volatil)
  714.     fprintf (outfile, "/v");
  715.  
  716.   if (in_rtx->unchanging)
  717.     fprintf (outfile, "/u");
  718.  
  719.   if (in_rtx->integrated)
  720.     fprintf (outfile, "/i");
  721.  
  722.   if (GET_MODE (in_rtx) != VOIDmode)
  723.     fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
  724.  
  725.   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
  726.  
  727.   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
  728.     switch (*format_ptr++)
  729.       {
  730.       case 's':
  731.     if (XSTR (in_rtx, i) == 0)
  732.       fprintf (outfile, " \"\"");
  733.     else
  734.       fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
  735.     sawclose = 1;
  736.     break;
  737.  
  738.     /* 0 indicates a field for internal use that should not be printed.  */
  739.       case '0':
  740.     break;
  741.  
  742.       case 'e':
  743.     indent += 2;
  744.     if (!sawclose)
  745.       fprintf (outfile, " ");
  746.     print_rtx (XEXP (in_rtx, i));
  747.     indent -= 2;
  748.     break;
  749.  
  750.       case 'E':
  751.     indent += 2;
  752.     if (sawclose)
  753.       {
  754.         fprintf (outfile, "\n%s",
  755.              (spaces + (sizeof spaces - indent * 2)));
  756.         sawclose = 0;
  757.       }
  758.     fprintf (outfile, "[ ");
  759.     if (NULL != XVEC (in_rtx, i))
  760.       {
  761.         indent += 2;
  762.         if (XVECLEN (in_rtx, i))
  763.           sawclose = 1;
  764.  
  765.         for (j = 0; j < XVECLEN (in_rtx, i); j++)
  766.           print_rtx (XVECEXP (in_rtx, i, j));
  767.  
  768.         indent -= 2;
  769.       }
  770.     if (sawclose)
  771.       fprintf (outfile, "\n%s",
  772.            (spaces + (sizeof spaces - indent * 2)));
  773.  
  774.     fprintf (outfile, "] ");
  775.     sawclose = 1;
  776.     indent -= 2;
  777.     break;
  778.  
  779.       case 'i':
  780.     fprintf (outfile, " %d", XINT (in_rtx, i));
  781.     sawclose = 0;
  782.     break;
  783.  
  784.       case 'u':
  785.     if (XEXP (in_rtx, i) != NULL)
  786.       fprintf(outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
  787.     else
  788.       fprintf(outfile, " 0");
  789.     sawclose = 0;
  790.     break;
  791.  
  792.       default:
  793.     fprintf (stderr,
  794.          "switch format wrong in rtl.print_rtx(). format was: %c.\n",
  795.          format_ptr[-1]);
  796.     abort ();
  797.       }
  798.  
  799.   fprintf (outfile, ")");
  800.   sawclose = 1;
  801. }
  802.  
  803. /* Call this function from the debugger to see what X looks like.  */
  804.  
  805. void
  806. debug_rtx (x)
  807.      rtx x;
  808. {
  809.   outfile = stderr;
  810.   print_rtx (x);
  811.   fprintf (stderr, "\n");
  812. }
  813.  
  814. /* External entry point for printing a chain of INSNs
  815.    starting with RTX_FIRST onto file OUTF.  */
  816.  
  817. void
  818. print_rtl (outf, rtx_first)
  819.      FILE *outf;
  820.      rtx rtx_first;
  821. {
  822.   register rtx tmp_rtx;
  823.  
  824.   outfile = outf;
  825.   sawclose = 0;
  826.  
  827.   for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
  828.     {
  829.       print_rtx (tmp_rtx);
  830.       fprintf (outfile, "\n");
  831.     }
  832. }
  833.  
  834. /* Subroutines of read_rtx.  */
  835.  
  836. /* Dump code after printing a message.  Used when read_rtx finds
  837.    invalid data.  */
  838.  
  839. static void
  840. dump_and_abort (expected_c, actual_c, infile)
  841.      int expected_c, actual_c;
  842.      FILE *infile;
  843. {
  844.   int c, i;
  845.  
  846.   fprintf (stderr,
  847.        "Expected character %c. Read character %c. At file position: %ld\n",
  848.        expected_c, actual_c, ftell (infile));
  849.   fprintf (stderr, "Following characters are:\n\t");
  850.   for (i = 0; i < 200; i++)
  851.     {
  852.       c = getc (infile);
  853.       if (EOF == c) break;
  854.       putc (c, stderr);
  855.     }
  856.   fprintf (stderr, "Aborting.\n");
  857.   abort ();
  858. }
  859.  
  860. /* Read chars from INFILE until a non-whitespace char
  861.    and return that.  Comments, both Lisp style and C style,
  862.    are treated as whitespace.
  863.    Tools such as genflags use this function.  */
  864.  
  865. int
  866. read_skip_spaces (infile)
  867.      FILE *infile;
  868. {
  869.   register int c;
  870.   while (c = getc (infile))
  871.     {
  872.       if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
  873.     ;
  874.       else if (c == ';')
  875.     {
  876.       while ((c = getc (infile)) && c != '\n') ;
  877.     }
  878.       else if (c == '/')
  879.     {
  880.       register int prevc;
  881.       c = getc (infile);
  882.       if (c != '*')
  883.         dump_and_abort ('*', c, infile);
  884.       
  885.       prevc = 0;
  886.       while (c = getc (infile))
  887.         {
  888.           if (prevc == '*' && c == '/')
  889.         break;
  890.           prevc = c;
  891.         }
  892.     }
  893.       else break;
  894.     }
  895.   return c;
  896. }
  897.  
  898. /* Read an rtx code name into the buffer STR[].
  899.    It is terminated by any of the punctuation chars of rtx printed syntax.  */
  900.  
  901. static void
  902. read_name (str, infile)
  903.      char *str;
  904.      FILE *infile;
  905. {
  906.   register char *p;
  907.   register int c;
  908.  
  909.   c = read_skip_spaces(infile);
  910.  
  911.   p = str;
  912.   while (1)
  913.     {
  914.       if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
  915.     break;
  916.       if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
  917.       || c == '(' || c == '[')
  918.     {
  919.       ungetc (c, infile);
  920.       break;
  921.     }
  922.       *p++ = c;
  923.       c = getc (infile);
  924.     }
  925.   *p = NULL;
  926. }
  927.  
  928. /* Read an rtx in printed representation from INFILE
  929.    and return an actual rtx in core constructed accordingly.
  930.    read_rtx is not used in the compiler proper, but rather in
  931.    the utilities gen*.c that construct C code from machine descriptions.  */
  932.  
  933. rtx
  934. read_rtx (infile)
  935.      FILE *infile;
  936. {
  937.   register int i, j, list_counter;
  938.   RTX_CODE tmp_code;
  939.   register char *format_ptr;
  940.   /* tmp_char is a buffer used for reading decimal integers
  941.      and names of rtx types and machine modes.
  942.      Therefore, 256 must be enough.  */
  943.   char tmp_char[256];
  944.   rtx return_rtx;
  945.   register int c;
  946.   int tmp_int;
  947.  
  948.   /* Linked list structure for making RTXs: */
  949.   struct rtx_list
  950.     {
  951.       struct rtx_list *next;
  952.       rtx value;        /* Value of this node...        */
  953.     };
  954.  
  955.   c = read_skip_spaces (infile); /* Should be open paren.  */
  956.   if (c != '(')
  957.     dump_and_abort ('(', c, infile);
  958.  
  959.   read_name (tmp_char, infile);
  960.  
  961.   tmp_code = UNKNOWN;
  962.  
  963.   for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
  964.     {
  965.       if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
  966.     {
  967.       tmp_code = (RTX_CODE) i;    /* get value for name */
  968.       break;
  969.     }
  970.     }
  971.   if (tmp_code == UNKNOWN)
  972.     {
  973.       fprintf (stderr,
  974.            "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
  975.            tmp_char);
  976.     }
  977.   /* (NIL) stands for an expression that isn't there.  */
  978.   if (tmp_code == NIL)
  979.     {
  980.       /* Discard the closeparen.  */
  981.       while ((c = getc (infile)) && c != ')');
  982.       return 0;
  983.     }
  984.  
  985.   return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
  986.                        then we free this space below.  */
  987.   format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
  988.  
  989.   /* If what follows is `: mode ', read it and
  990.      store the mode in the rtx.  */
  991.  
  992.   i = read_skip_spaces (infile);
  993.   if (i == ':')
  994.     {
  995.       register int k;
  996.       read_name (tmp_char, infile);
  997.       for (k = 0; k < NUM_MACHINE_MODES; k++)
  998.     if (!strcmp (GET_MODE_NAME (k), tmp_char))
  999.       break;
  1000.  
  1001.       PUT_MODE (return_rtx, (enum machine_mode) k );
  1002.     }
  1003.   else
  1004.     ungetc (i, infile);
  1005.  
  1006.   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
  1007.     switch (*format_ptr++)
  1008.       {
  1009.     /* 0 means a field for internal use only.
  1010.        Don't expect it to be present in the input.  */
  1011.       case '0':
  1012.     break;
  1013.  
  1014.       case 'e':
  1015.       case 'u':
  1016.     XEXP (return_rtx, i) = read_rtx (infile);
  1017.     break;
  1018.  
  1019.       case 'E':
  1020.     {
  1021.       register struct rtx_list *next_rtx, *rtx_list_link;
  1022.       struct rtx_list *list_rtx;
  1023.  
  1024.       c = read_skip_spaces (infile);
  1025.       if (c != '[')
  1026.         dump_and_abort ('[', c, infile);
  1027.  
  1028.       /* add expressions to a list, while keeping a count */
  1029.       next_rtx = NULL;
  1030.       list_counter = 0;
  1031.       while ((c = read_skip_spaces (infile)) && c != ']')
  1032.         {
  1033.           ungetc (c, infile);
  1034.           list_counter++;
  1035.           rtx_list_link = (struct rtx_list *)
  1036.         alloca (sizeof (struct rtx_list));
  1037.           rtx_list_link->value = read_rtx (infile);
  1038.           if (next_rtx == 0)
  1039.         list_rtx = rtx_list_link;
  1040.           else
  1041.         next_rtx->next = rtx_list_link;
  1042.           next_rtx = rtx_list_link;
  1043.           rtx_list_link->next = 0;
  1044.         }
  1045.       /* get vector length and allocate it */
  1046.       XVEC (return_rtx, i) = (list_counter
  1047.                   ? rtvec_alloc (list_counter)
  1048.                   : NULL);
  1049.       if (list_counter > 0) 
  1050.         {
  1051.           next_rtx = list_rtx;
  1052.           for (j = 0; j < list_counter; j++,
  1053.            next_rtx = next_rtx->next)
  1054.         XVECEXP (return_rtx, i, j) = next_rtx->value;
  1055.         }
  1056.       /* close bracket gotten */
  1057.     }
  1058.     break;
  1059.  
  1060.       case 's':
  1061.     {
  1062.       int saw_paren = 0;
  1063.       register char *stringbuf;
  1064.       int stringbufsize;
  1065.  
  1066.       c = read_skip_spaces (infile);
  1067.       if (c == '(')
  1068.         {
  1069.           saw_paren = 1;
  1070.           c = read_skip_spaces (infile);
  1071.         }
  1072.       if (c != '"')
  1073.         dump_and_abort ('"', c, infile);
  1074.       j = 0;
  1075.       stringbufsize = 10;
  1076.       stringbuf = (char *) xmalloc (stringbufsize + 1);
  1077.  
  1078.       while (1)
  1079.         {
  1080.           if (j >= stringbufsize - 4)
  1081.         {
  1082.           stringbufsize *= 2;
  1083.           stringbuf = (char *) xrealloc (stringbuf, stringbufsize + 1);
  1084.         }
  1085.           stringbuf[j] = getc (infile); /* Read the string  */
  1086.           if (stringbuf[j] == '\\')
  1087.         {
  1088.           stringbuf[j] = getc (infile);    /* Read the string  */
  1089.           /* \; makes stuff for a C string constant containing
  1090.              newline and tab.  */
  1091.           if (stringbuf[j] == ';')
  1092.             {
  1093.               strcpy (&stringbuf[j], "\\n\\t");
  1094.               j += 3;
  1095.             }
  1096.         }
  1097.           else if (stringbuf[j] == '"')
  1098.         break;
  1099.           j++;
  1100.         }
  1101.  
  1102.       stringbuf[j] = 0;    /* NUL terminate the string  */
  1103.       stringbuf = (char *) xrealloc (stringbuf, j + 1);
  1104.  
  1105.       if (saw_paren)
  1106.         {
  1107.           c = read_skip_spaces (infile);
  1108.           if (c != ')')
  1109.         dump_and_abort (')', c, infile);
  1110.         }
  1111.       XSTR (return_rtx, i) = stringbuf;
  1112.     }
  1113.     break;
  1114.  
  1115.       case 'i':
  1116.     read_name (tmp_char, infile);
  1117.     tmp_int = atoi (tmp_char);
  1118.     XINT (return_rtx, i) = tmp_int;
  1119.     break;
  1120.  
  1121.       default:
  1122.     fprintf (stderr,
  1123.          "switch format wrong in rtl.read_rtx(). format was: %c.\n",
  1124.          format_ptr[-1]);
  1125.     fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
  1126.     abort ();
  1127.       }
  1128.  
  1129.   c = read_skip_spaces (infile);
  1130.   if (c != ')')
  1131.     dump_and_abort (')', c, infile);
  1132.  
  1133.   return return_rtx;
  1134. }
  1135.  
  1136. /* This is called once per compilation, before any rtx's are constructed.
  1137.    It initializes the vector `rtx_length'.  */
  1138.  
  1139. void
  1140. init_rtl ()
  1141. {
  1142.   int i;
  1143.  
  1144.   for (i = 0; i < NUM_RTX_CODE; i++)
  1145.     rtx_length[i] = strlen (rtx_format[i]);
  1146. }
  1147.